package com.zzl.bonds.ticket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzl.bonds.ticket.dao.SubsidiaryQuotaDao;
import com.zzl.bonds.ticket.dto.SubsidiaryQuotaAddDto;
import com.zzl.bonds.ticket.dto.SubsidiaryQuotaUpdateDto;
import com.zzl.bonds.ticket.dto.credit.CreditSelectDto;
import com.zzl.bonds.ticket.entity.CoreEnterpriseCreditEntity;
import com.zzl.bonds.ticket.entity.SubsidiaryQuotaEntity;
import com.zzl.bonds.ticket.service.CoreEnterpriseCreditService;
import com.zzl.bonds.ticket.service.SubsidiaryQuotaService;
import com.zzl.general.common.exception.SysException;
import com.zzl.general.common.serurity.entity.User;
import com.zzl.general.common.utils.PageUtils;
import com.zzl.general.common.utils.Query;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 分公司集团授信额度管理
 *
 * @author sunpp
 * @date 2022-03-01 11:26:07
 */
@Service("subsidiaryQuotaService")
public class SubsidiaryQuotaServiceImpl extends ServiceImpl<SubsidiaryQuotaDao, SubsidiaryQuotaEntity> implements SubsidiaryQuotaService {


    @Autowired
    private CoreEnterpriseCreditService coreEnterpriseCreditService;


    /**
     * 处理 分公司的 额度的 扣减
     *
     * @param id     额度id
     * @param amount 数量
     * @param user   登录用户
     * @return 核心企业的 授信id
     */
    @Override
    public String handReduceSubQuota(String id, Double amount, User user) {
        SubsidiaryQuotaEntity entity = getById(id);
        entity.setFrozenAmount(entity.getFrozenAmount() - amount);
        entity.setSurplusAmount(entity.getSurplusAmount() - amount);
        entity.setUsedAmount(entity.getUsedAmount() + amount);
        this.updateById(entity);
        return entity.getCoreEnterpriseCreditId();
    }

    /**
     * 供应商 拒绝签收后 额度的 回滚
     *
     * @param id     额度id
     * @param amount 数量
     * @param user   登录用户
     * @return 核心企业的 授信id
     */
    @Override
    public String rollBackSubQuota(String id, Double amount, User user) {
        SubsidiaryQuotaEntity entity = getById(id);
        if (entity.getFrozenAmount() - amount > 0) {
            entity.setFrozenAmount(entity.getFrozenAmount() - amount);
        } else {
            entity.setFrozenAmount(0.0);
        }
        entity.setAvailableAmount(entity.getAvailableAmount() + amount);
        entity.setUpdaterId(user.getId());
        entity.setUpdateTime(new Date());
        this.updateById(entity);
        return entity.getCoreEnterpriseCreditId();
    }

    /**
     * 分公司的 集团授信
     * 处理 核心企业 或者厂子的 的冻结 金额
     * 适用 开立中 转让中 融资中 将金额冻结
     */
    @Override
    public String handSubQuota(String id, Double amount, User user) {
        SubsidiaryQuotaEntity entity = getById(id);
        entity.setFrozenAmount(entity.getFrozenAmount() + amount);
        entity.setAvailableAmount(entity.getAvailableAmount() - amount);
        entity.setUpdaterId(user.getId());
        entity.setUpdateTime(new Date());
        this.updateById(entity);
        return entity.getCoreEnterpriseCreditId();
    }

    /**
     * 根据v 企业id 查找厂子的 集团授信
     *
     * @param enterpriseId 企业id
     * @return 授信情况
     */
    @Override
    public List<CreditSelectDto> getSubQuotaByEnterpriseId(String enterpriseId) {
        List<CreditSelectDto> list = new ArrayList<>();
        QueryWrapper<SubsidiaryQuotaEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(SubsidiaryQuotaEntity::getEnterpriseId, enterpriseId)
                .eq(SubsidiaryQuotaEntity::getLatestStatus, 1);
        // 分公司的额度
        List<SubsidiaryQuotaEntity> creditEntities = this.list(queryWrapper);
        if (!CollectionUtils.isEmpty(creditEntities)) {
            // 集团的 可用额度
            List<String> ids = creditEntities.stream().map(SubsidiaryQuotaEntity::getCoreEnterpriseCreditId).distinct().collect(Collectors.toList());
            List<CoreEnterpriseCreditEntity> coreCreditIds = coreEnterpriseCreditService.getEntityByCoreCreditIds(ids);
            Map<String, CoreEnterpriseCreditEntity> map = coreCreditIds.stream().collect(Collectors.toMap(CoreEnterpriseCreditEntity::getId, v -> v, (a, b) -> a));
            for (SubsidiaryQuotaEntity quotaEntity : creditEntities) {
                CreditSelectDto dto = new CreditSelectDto();
                dto.setId(quotaEntity.getId());
                dto.setInstitutyId(quotaEntity.getInstitutyId());
                String str = quotaEntity.getCreditNo() + "-" + quotaEntity.getInstitutyName() + "-";
                // 比较金额
                CoreEnterpriseCreditEntity core = map.get(quotaEntity.getCoreEnterpriseCreditId());
                if (!ObjectUtils.isEmpty(core) && core.getCreditAvailableAmount() < quotaEntity.getAvailableAmount()) {
                    dto.setCreditDescribe(str + core.getCreditAvailableAmount());
                } else {
                    dto.setCreditDescribe(str + quotaEntity.getAvailableAmount());
                }
                list.add(dto);
            }
            return list;
        }
        return list;
    }

    /**
     * 获取分公司的 额度管理
     *
     * @param coreEnterpriseCreditId 核心企业的 id
     * @return list
     */
    @Override
    public List<SubsidiaryQuotaEntity> getSubQuotaList(String coreEnterpriseCreditId) throws SysException {
        QueryWrapper<SubsidiaryQuotaEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SubsidiaryQuotaEntity::getCoreEnterpriseCreditId, coreEnterpriseCreditId)
                .eq(SubsidiaryQuotaEntity::getLatestStatus, 1);
        List<SubsidiaryQuotaEntity> list = this.list(queryWrapper);
        // 判断 分公司的 可用授信额度 与 集团剩余剩余 授信额度的 大小 去小值
        CoreEnterpriseCreditEntity coreEntity = coreEnterpriseCreditService.getEntityById(coreEnterpriseCreditId);
        if (ObjectUtils.isEmpty(coreEntity)) {
            throw new SysException("未找到集团授信数据");
        }
        Double surplusAmount = coreEntity.getCreditSurplusAmount();
        if (!CollectionUtils.isEmpty(list)) {
            for (SubsidiaryQuotaEntity quotaEntity : list) {
                if (quotaEntity.getSurplusAmount() == null || quotaEntity.getSurplusAmount() > surplusAmount) {
                    // 重新设置 剩余额度金额 共享额度的 总值
                    quotaEntity.setSurplusAmount(surplusAmount);
                }
            }
        }
        return list;
    }


    /**
     * 分页查询
     *
     * @param params 查询参数
     * @return 分页数据
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SubsidiaryQuotaEntity> page = this.page(
                new Query<SubsidiaryQuotaEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    /**
     * 新增
     *
     * @param subsidiaryQuotaAddDto 新增实体
     * @param user                  当前登录用户
     * @throws SysException 业务异常
     */
    @Override
    public void saveSubsidiaryQuota(SubsidiaryQuotaAddDto subsidiaryQuotaAddDto, User user) throws SysException {
        SubsidiaryQuotaEntity subsidiaryQuotaEntity = new SubsidiaryQuotaEntity();
        BeanUtils.copyProperties(subsidiaryQuotaAddDto, subsidiaryQuotaEntity);
        subsidiaryQuotaEntity.setCreatorId(user.getId());
        if (!this.save(subsidiaryQuotaEntity)) {
            throw new SysException("A00001", "保存失败！");
        }
    }

    /**
     * 修改
     *
     * @param updateDto 修改实体
     * @param user      当前登录用户
     * @throws SysException 业务异常
     */
    @Override
    public void updateSubsidiaryQuotaById(SubsidiaryQuotaUpdateDto updateDto, User user) throws SysException {
        SubsidiaryQuotaEntity newSubsidiaryQuot = new SubsidiaryQuotaEntity();
        SubsidiaryQuotaEntity subsidiaryQuotaEntity = this.getById(updateDto.getId());
        if (ObjectUtils.isEmpty(subsidiaryQuotaEntity)) {
            throw new SysException("未找到分公司额度");
        }
        // 校验 额度上限不能大于 集团企业的 授信总额度
        CoreEnterpriseCreditEntity coreEntity = coreEnterpriseCreditService.getEntityById(subsidiaryQuotaEntity.getCoreEnterpriseCreditId());
        if (ObjectUtils.isEmpty(coreEntity)) {
            throw new SysException("未找到核心企业数据");
        }
        if (updateDto.getQuotaMaxLimit() > coreEntity.getCreditAllAmount()) {
            throw new SysException("额度上限不可大于集团企业的授信总额度");
        }
        BeanUtils.copyProperties(updateDto, newSubsidiaryQuot);
        newSubsidiaryQuot.setUpdaterId(user.getId());
        //计算可用余额
        Double surplusAmount;
        if (null == subsidiaryQuotaEntity.getSurplusAmount()) {
            surplusAmount = updateDto.getQuotaMaxLimit();
        } else {
            surplusAmount = updateDto.getQuotaMaxLimit() - subsidiaryQuotaEntity.getQuotaMaxLimit() + subsidiaryQuotaEntity.getSurplusAmount();
        }
        newSubsidiaryQuot.setSurplusAmount(surplusAmount);
        if (!this.updateById(newSubsidiaryQuot)) {
            throw new SysException("A00002", "修改失败！");
        }
    }

}